using System;
using System.Collections;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace MediaOwl.Common.ControlTemplates
{
    /// <summary>
    /// A control to provide an area where a Dialog can pop up.
    /// </summary>
    /// <QualityBand>Preview</QualityBand>
    [TemplateVisualState(Name = "Visible", GroupName = "DialogStates")]
    [TemplateVisualState(Name = "Hidden", GroupName = "DialogStates")]
    [StyleTypedProperty(Property = "OverlayStyle", StyleTargetType = typeof(Border))]
    public class DialogIndicator : ContentControl
    {

        #region Fields

        private Storyboard hidden;
        private FrameworkElement root;
        private const string VsmGroupName = "DialogStates";

        #endregion

        #region ctor
        /// <summary>
        /// Instantiates a new instance of the DialogIndicator control.
        /// </summary>
        public DialogIndicator()
        {
            DefaultStyleKey = typeof(DialogIndicator);
            Loaded += DialogIndicatorLoaded;
            Unloaded += DialogIndicatorUnloaded;      
        }

        #endregion

        #region DependencyProperties

        #region OverlayStyleProperty

        /// <summary>
        /// Identifies the OverlayStyle dependency property.
        /// </summary>
        public static readonly DependencyProperty OverlayStyleProperty = DependencyProperty.Register(
            "OverlayStyle",
            typeof(Style),
            typeof(DialogIndicator),
            new PropertyMetadata(null));

        /// <summary>
        /// Gets or sets a value indicating the style to use for the overlay.
        /// </summary>
        public Style OverlayStyle
        {
            get { return (Style)GetValue(OverlayStyleProperty); }
            set { SetValue(OverlayStyleProperty, value); }
        }

        #endregion

        #endregion

        #region Methods

        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);
            VisualStateManager.GoToState(this, newContent != null ? "Visible" : "Hidden", true);
        }

        void DialogIndicatorUnloaded(object sender, RoutedEventArgs e)
        {
            if (hidden != null)
                hidden.Completed += HiddenCompleted;
        }

        void DialogIndicatorLoaded(object sender, RoutedEventArgs e)
        {
            root = GetTemplateChild("Root") as FrameworkElement;
            if (root != null)
            {
                IList groups = VisualStateManager.GetVisualStateGroups(root);
                IList states = (from VisualStateGroup vsg in groups where vsg.Name == VsmGroupName select vsg.States).FirstOrDefault();

                if (states != null)
                {
                    foreach (VisualState state in states)
                    {
                        if (state.Name == "Hidden")
                        {
                            hidden = state.Storyboard;
                            hidden.Completed += HiddenCompleted;
                        }
                    }
                }
            }
        } 

        private void HiddenCompleted(object sender, EventArgs e)
        {
            SetValue(ContentProperty, null);
            hidden.Completed -= HiddenCompleted;
        }

        #endregion
    }
}